package memtable

//数字过滤
func (m *Table) WhereNull(idx int, not bool) *Table {
	t := m.CopySchema()
	for _, row := range m.rows {
		pval := row.Data[idx]
		if pval == nil {
			if !not {
				t.rows = append(t.rows, row)
			}
			continue
		}
		if _, ok := pval.(*float64); ok {
			if not {
				t.rows = append(t.rows, row)
			} else {
				t.rows = append(t.rows, row)
			}
		} else if _, ok := pval.(*string); ok {
			if not {
				t.rows = append(t.rows, row)
			} else {
				t.rows = append(t.rows, row)
			}
		}
	}
	return t
}

//2重函数，第一重逻辑函数，第二重数据函数
func (m *Table) WhereMath(idx1, idx2 int, y float64, eval func(x, y float64) bool, fmath func(x, y float64) float64) *Table {
	t := m.CopySchema()
	for _, row := range m.rows {
		pval1 := row.Data[idx1]
		if pval1 == nil {
			continue
		}
		pval2 := row.Data[idx2]
		if pval2 == nil {
			continue
		}
		if pvalue2, ok := pval2.(*float64); ok && pvalue2 != nil {
			fmath2 := fmath(*pvalue2, y)
			if pvalue1, ok := pval1.(*float64); ok && pvalue1 != nil {
				if eval(*pvalue1, fmath2) {
					t.rows = append(t.rows, row)
				}
			}
		}
	}
	return t
}

//数字过滤
func (m *Table) WhereNum(idx int, y float64, eval func(x, y float64) bool) *Table {
	t := m.CopySchema()
	for _, row := range m.rows {
		pval := row.Data[idx]
		if pval == nil {
			continue
		}
		if pvalue, ok := pval.(*float64); ok && pvalue != nil {
			if eval(*pvalue, y) {
				t.rows = append(t.rows, row)
			}
		}
	}
	return t
}

//数字过滤
func (m *Table) WhereNumArray(idx int, y []float64, eval func(x float64, y []float64) bool) *Table {
	t := m.CopySchema()
	for _, row := range m.rows {
		pval := row.Data[idx]
		if pval == nil {
			continue
		}
		if pvalue, ok := pval.(*float64); ok && pvalue != nil {
			if eval(*pvalue, y) {
				t.rows = append(t.rows, row)
			}
		}
	}
	return t
}

//字符串过滤
func (m *Table) WhereStr(idx int, y string, eval func(x, y string) bool) *Table {
	t := m.CopySchema()
	for _, row := range m.rows {
		pval := row.Data[idx]
		if pval == nil {
			continue
		}
		if pvalue, ok := pval.(*string); ok && pvalue != nil {
			if eval(*pvalue, y) {
				t.rows = append(t.rows, row)
			}
		}
	}
	return t
}

//字符串过滤
func (m *Table) WhereStrArray(idx int, y []string, eval func(x string, y []string) bool) *Table {
	t := m.CopySchema()
	for _, row := range m.rows {
		pval := row.Data[idx]
		if pval == nil {
			continue
		}
		if pvalue, ok := pval.(*string); ok && pvalue != nil {
			if eval(*pvalue, y) {
				t.rows = append(t.rows, row)
			}
		}
	}
	return t
}

// 分组查询
func (m *Table) GroupBy(names []string) []*Table {
	ts := []*Table{m}
	for _, name := range names {
		ts = m.groupBy(name, ts)
	}
	return ts
}

func (m *Table) groupBy(name string, tms []*Table) []*Table {
	idx, ok := m.columnIndex[name]
	if !ok {
		return nil
	}
	if m.columnType[idx] == TypeNumber {
		tables := make([]*Table, 0)
		for _, table := range tms {
			mapTable := make(map[float64]*Table)
			for _, row := range table.rows {
				pval := row.Data[idx]
				if pval == nil {
					continue
				}
				if id, ok := pval.(*float64); ok && id != nil {
					t, ok := mapTable[*id]
					if !ok {
						t = m.CopySchema()
						mapTable[*id] = t
					}
					t.rows = append(t.rows, row)
				}
			}
			for _, t := range mapTable {
				tables = append(tables, t)
			}
		}
		return tables
	}
	tables := make([]*Table, 0)
	for _, table := range tms {
		mapTable := make(map[string]*Table)
		for _, row := range table.rows {
			pval := row.Data[idx]
			if pval == nil {
				continue
			}
			if id, ok := pval.(*string); ok && id != nil {
				t, ok := mapTable[*id]
				if !ok {
					t = m.CopySchema()
					mapTable[*id] = t
				}
				t.rows = append(t.rows, row)
			}
		}
		for _, t := range mapTable {
			tables = append(tables, t)
		}
	}

	return tables
}

// 请求平均值
func Avg(m *Table, idx int) float64 {
	if m.columnType[idx] != TypeNumber {
		return 0
	}
	sum := 0.0
	cnt := 0
	for _, row := range m.rows {
		pval := row.Data[idx]
		if pval == nil {
			continue
		}
		if value, ok := pval.(*float64); ok && value != nil {
			sum += *value
			cnt++
		}
	}
	if cnt == 0 {
		return 0
	}
	return sum / float64(cnt)
}

// 求和
func Sum(m *Table, idx int) float64 {
	if m.columnType[idx] != TypeNumber {
		return 0
	}
	sum := 0.0
	for _, row := range m.rows {
		pval := row.Data[idx]
		if pval == nil {
			continue
		}
		if value, ok := pval.(*float64); ok && value != nil {
			sum += *value
		}
	}

	return sum
}

func Max(m *Table, idx int) float64 {
	if m.columnType[idx] != TypeNumber {
		return 0
	}

	max := 0.0
	first := true
	for _, row := range m.rows {
		pval := row.Data[idx]
		if pval == nil {
			continue
		}
		if value, ok := pval.(*float64); ok && value != nil {
			if first {
				max = *value
				first = false
			} else {
				if max < *value {
					max = *value
				}
			}
		}
	}

	return max
}

func Min(m *Table, idx int) float64 {
	if m.columnType[idx] != TypeNumber {
		return 0
	}

	min := 0.0
	first := true
	for _, row := range m.rows {
		pval := row.Data[idx]
		if pval == nil {
			continue
		}
		if value, ok := pval.(*float64); ok && value != nil {
			if first {
				min = *value
				first = false
			} else {
				if min > *value {
					min = *value
				}
			}
		}
	}

	return min
}

// 统计
func Count(m *Table, idx int) float64 {
	return float64(len(m.rows))
}
